#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>

FILE * rnd;

#ifndef DEVRANDOM
#if defined(__OpenBSD__) 
#define DEVRANDOM "/dev/arandom"
#elif defined(__Linux__)
#define DEVRANDOM "/dev/random"
#else
#error "What's a good random device?"
#endif /* if os */
#endif /* ifndef */

unsigned long	randulong	(unsigned long size);
unsigned long	getrandulong	();
void		usage		(int detailed);

#define SIZE 8

static const char* chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ`~!@#$%^&*()-_=+|\[]{};:,./<>?";

static const int letternumlen = 62;
static const int punctlen = 92;

static char * _progname;

int
main(int argc, char * argv[]){
	int stringlen = SIZE;
	char *outp;
	int i;
	int sourcelen = letternumlen;

	char c;
	extern char *optarg;
	extern int optind, opterr, optopt;

	_progname = argv[0];

	while((c = getopt(argc, argv, "c:s:h")) != EOF) switch (c)
	{
		case 'c':
			if((i=atoi(optarg)) > 0)
				stringlen = i;
			else
				usage(0);
			break;
		case 's':
			if((i=atoi(optarg)) > 0)
				sourcelen = i;
			else
				usage(0);
			break;
		case 'h':
			usage(1);
			break;
		case ':':
		case '?':
			usage(0);
	}

	outp = calloc(stringlen + 1, sizeof(char));

	if((rnd = fopen(DEVRANDOM, "r")) == NULL) {
		printf("Unable to open %s\n", DEVRANDOM);
		exit(-1);
	}

	for (i = 0 ; i < stringlen ; i++) {
		outp[i] = chars[randulong(sourcelen)];
		printf("%c", outp[i]);
	}
	printf("\n");
	outp[stringlen]=0;
	fclose(rnd);
	exit(0);
}

unsigned long randulong (unsigned long size){
	return (getrandulong() % size);
}

unsigned long getrandulong (){
	unsigned long ul;
	fread(&ul, sizeof(unsigned long), 1, rnd);
	return ul;
}

void usage(int detailed)
{

	printf("Usage: %s [-c #] [-s #] [ -h]\n", _progname);

	if(detailed){
		printf("\n-c\tThe number of characters in the output string\n");
		printf("\t(default is 8)\n");
		printf("-s\tThe number of characters from the input string to use\n");
		printf("\tthe input string is: %s\n", chars);
		printf("\t(default is 62, max is %d)\n", strlen(chars));
		printf("-h\tDisplay this statement\n");
	}
	exit(-1);
}

